package com.gep.session.impl.manager;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;

import com.gep.dto.EquipamentoDTO;
import com.gep.dto.PecaDTO;
import com.gep.entity.Equipamento;
import com.gep.entity.ItemSolicitacao;
import com.gep.session.manager.GerencialBORemota;
import com.gep.util.Conversor;

@Stateless(mappedName = "ejb/gep/GerencialBORemota")
public class GerencialBO implements GerencialBORemota {

	private static final Logger LOGGER = Logger
			.getLogger(GerencialBORemota.class);

	@PersistenceContext
	private EntityManager em;

	public Object[] ocorrenciasFrequentes() {
		// TODO Auto-generated method stub
		return null;
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> acompanharSaidaDePecas(Date inicio, Date fim,
			EquipamentoDTO equipamentoDTO) {
		List<Object[]> lista = null;
		if (equipamentoDTO != null) {
			Equipamento equipamento = em.find(Equipamento.class, equipamentoDTO
					.getCodEquipamento());
			Query query = em
					.createQuery("SELECT p ,sum(its.quantidade) "
							+ "FROM ItemSolicitacao its, Peca p, Equipamento e "
							+ "WHERE  its.peca = p and e = p.equipamento and e = :pEquipamento "
							+ "and its.solicitacao.dataSolicitacao between :pInicio "
							+ "and :pFinal " + "GROUP BY p.nomePeca "
							+ "ORDER BY sum(its.quantidade) DESC");
			query.setParameter("pInicio", inicio);
			query.setParameter("pFinal", fim);
			query.setParameter("pEquipamento", equipamento);
			query.setMaxResults(5);
			lista = (List) query.getResultList();

			for (Object[] object : lista) {

				PecaDTO pecaDTO = (PecaDTO) Conversor.converter(object[0],
						PecaDTO.class.getName());
				object[0] = (Object) pecaDTO;

			}

		} else {
			Query query = em
					.createQuery("SELECT p ,sum(its.quantidade) "
							+ "FROM ItemSolicitacao its, Peca p "
							+ "WHERE  its.peca = p "
							+ "and its.solicitacao.dataSolicitacao between :pInicio and :pFinal "
							+ "GROUP BY p.nomePeca "
							+ "ORDER BY sum(its.quantidade) DESC");
			query.setParameter("pInicio", inicio);
			query.setParameter("pFinal", fim);
			query.setMaxResults(5);
			lista = (List) query.getResultList();

			for (Object[] object : lista) {

				PecaDTO pecaDTO = (PecaDTO) Conversor.converter(object[0],
						PecaDTO.class.getName());
				object[0] = (Object) pecaDTO;

			}
		}
		return lista;
	}

	public List<Object[]> acompanharTempoReparo(Date inicio, Date fim,
			EquipamentoDTO equipamentoDTO) {
		List<Object[]> lista;
		Equipamento equipamento = em.find(Equipamento.class, equipamentoDTO
				.getCodEquipamento());
		Query query = em
				.createQuery("SELECT e ,p ,(sum(DATEDIFF(r.dataReparo,o.dataQuebra))/COUNT(*)) "
						+ "FROM Equipamento e,Peca p,ItemSolicitacao its, Ocorrencia o, Reparo r "
						+ "WHERE p.equipamento = e and its.peca = p "
						+ "and its.ocorrencia = o and o.reparo = r and e = :pEquipamento "
						+ "and its.solicitacao.dataSolicitacao between :pInicio and :pFinal "
						+ "GROUP BY p.codPeca ORDER BY p.nomePeca");
		query.setParameter("pInicio", inicio);
		query.setParameter("pFinal", fim);
		query.setParameter("pEquipamento", equipamento);
		query.setMaxResults(5);
		lista = (List) query.getResultList();
		for (Object[] object : lista) {

			EquipamentoDTO dto = (EquipamentoDTO) Conversor.converter(
					object[0], EquipamentoDTO.class.getName());
			object[0] = (Object) dto;
			PecaDTO pecaDTO = (PecaDTO) Conversor.converter(object[1],
					PecaDTO.class.getName());
			object[1] = (Object) pecaDTO;

		}

		return lista;

	}

	public List<Object[]> acompanharOcorrenciaFrequente(Date inicio, Date fim,
			EquipamentoDTO equipamentoDTO) {
		List<Object[]> lista;
		Equipamento equipamento = em.find(Equipamento.class, equipamentoDTO
				.getCodEquipamento());
		Query query = em
				.createQuery("SELECT m.nome,COUNT(*),e FROM Equipamento e, ItemSolicitacao its, "
						+ "Peca p, Ocorrencia o,Motivo m "
						+ "WHERE its.peca = p and e = p.equipamento "
						+ "and its.ocorrencia = o "
						+ "and o.motivo = m and e = :pEquipamento "
						+ "and its.solicitacao.dataSolicitacao between :pInicio and :pFinal "
						+ "GROUP BY m.nome ORDER BY COUNT(*) DESC");

		query.setParameter("pInicio", inicio);
		query.setParameter("pFinal", fim);
		query.setParameter("pEquipamento", equipamento);
		lista = (List) query.getResultList();
		for (Object[] object : lista) {

			EquipamentoDTO dto = (EquipamentoDTO) Conversor.converter(
					object[2], EquipamentoDTO.class.getName());
			object[2] = (Object) dto;

		}
		return lista;

	}

	public List<Object[]> acompanharIndiceReparo(Date inicio, Date fim,
			PecaDTO pecaDTO) {

		List<Date> listaObjectPecaDtReparo = new ArrayList<Date>();
		List<Object[]> listaObjectEq = new ArrayList<Object[]>();

		if (pecaDTO != null) {
			Integer codPeca = pecaDTO.getCodPeca();

			Query query = em
					.createNativeQuery("select r.dt_reparo from  tb_item_solicitacao its, "
							+ "tb_solicitacao s,tb_peca p, tb_ocorrencia o,"
							+ "tb_reparo r "
							+ "where its.cod_peca = p.cod_peca "
							+ "and its.cod_solicitacao = s.cod_solicitacao "
							+ "and its.cod_ocorrencia = o.cod_ocorrencia "
							+ "and o.cod_reparo = r.cod_reparo "
							+ "and p.cod_peca = :pPeca "
							+ "and s.dt_solicitacao "
							+ "BETWEEN  :pInicio and :pFinal "
							+ "Order By r.dt_reparo asc");

			query.setParameter("pPeca", codPeca);
			query.setParameter("pInicio", inicio);
			query.setParameter("pFinal", fim);

			listaObjectPecaDtReparo = (List) query.getResultList();

			for (Date objectDtReparo : listaObjectPecaDtReparo) {

				Object[] objectsDateDiff = new Object[4];
				Date  objectDtQuebra;

				query = em.createNativeQuery("select o.dt_quebra "
						+ "from  tb_item_solicitacao its, "
						+ "tb_solicitacao s,tb_peca p, tb_ocorrencia o "
						+ "where its.cod_peca = :pCodPeca "
						+ "and its.cod_solicitacao = s.cod_solicitacao "
						+ "and its.cod_ocorrencia = o.cod_ocorrencia "
						+ "and o.dt_quebra > :pDataReparo "
						+ "and s.dt_solicitacao "
						+ "BETWEEN  :pInicio and :pFinal "
						+ "Order By o.dt_quebra asc");

				query.setParameter("pInicio", inicio);
				query.setParameter("pFinal", fim);
				query.setParameter("pDataReparo", objectDtReparo);
				query.setParameter("pCodPeca", pecaDTO.getCodPeca());

				if (query.getResultList().iterator().hasNext()) {
					objectDtQuebra = (Date) query.getResultList()
							.iterator().next();
					
					objectsDateDiff[0] = objectDtReparo; //colocando no objeto a data de reparo
					objectsDateDiff[1] = objectDtQuebra; //colocando no objeto a data de quebra
					
					query = em.createNativeQuery("select datediff(:pDataQuebra,:pDataReparo) ");
					query.setParameter("pDataReparo", objectsDateDiff[0]);
					query.setParameter("pDataQuebra", objectsDateDiff[1]);
					
					objectsDateDiff[2] = query.getSingleResult();
					objectsDateDiff[3] = pecaDTO;
					
					listaObjectEq.add(objectsDateDiff);
					
				}
				
				//
			}

		}
		return listaObjectEq;
	}
}